﻿#include "userTasks.h"
#include "resource.h"
#include "GW_Rs485.h"
#include "GW_ModProtocol.h"
#include "GW_AdrDial.h"
#include "GW_RelayControl.h"

#define  MODE_AUTO   1
#define  MODE_STOP   2
#define  MODE_OPEN   3

GW_RS485 *com_transmit;
GW_ModProtocol pol_Transmit;
GW_AdrDial address;
u32 mask_relay_out = 0;
GW_RelayControl relay_out;
GW_RelayControl relay_open;
GW_RelayControl relay_close;
GW_RelayControl relay_auto;

GPIO_PinState  RIN1State;
GPIO_PinState  RIN2State;
GPIO_PinState  RIN3State;


int moduleID=0;
int workMode = 0;

bool checkPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,GPIO_PinState activeState)
{
   GPIO_PinState  newState;
   newState = HAL_GPIO_ReadPin(GPIOx, GPIO_Pin);
   if (newState == activeState)
   {
      osDelay(100);
      if (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == activeState)
      {
         return true;
      }
   }
   return false;
}

void changeMode(int newMode)
{
   switch (newMode)
   {
   case MODE_AUTO:
      {
         relay_auto.active();
         relay_close.unactive();
         relay_open.unactive();
         break;
      }
   case MODE_OPEN:
      {
         relay_open.active();
         relay_out.active();
         relay_auto. unactive();
         relay_close.unactive(); 
         break;
      }
   case MODE_STOP:
      {
         relay_close.active(); 
         relay_open.unactive();
         relay_out.unactive();
         relay_auto. unactive();
         break;
      }
   }
}

void task_do_default()
{
   bool isActive;
   int   newMode;

   relay_out.setMark(&mask_relay_out);
   relay_out.setCTLPin(RELAY4_GPIO_Port, RELAY4_Pin, GPIO_PIN_RESET);
   relay_out.setTimeOut(5);

   relay_open.setCTLPin(RELAY1_GPIO_Port, RELAY1_Pin, GPIO_PIN_RESET);
   relay_close.setCTLPin(RELAY2_GPIO_Port, RELAY2_Pin, GPIO_PIN_RESET);
   relay_auto.setCTLPin(RELAY3_GPIO_Port, RELAY3_Pin, GPIO_PIN_RESET);


   workMode = MODE_AUTO;
   changeMode(workMode);
   while (1)
   {
      //osSemaphoreWait(inputSemHandle, osWaitForever);
      isActive = checkPin(RIN1_GPIO_Port, RIN1_Pin, GPIO_PIN_RESET);
      if (isActive)
      {
         workMode = MODE_OPEN;
      }
      isActive = checkPin(RIN2_GPIO_Port, RIN2_Pin, GPIO_PIN_RESET);
      if (isActive)
      {
         workMode = MODE_STOP;
      }
      isActive = checkPin(RIN3_GPIO_Port, RIN3_Pin, GPIO_PIN_RESET);
      if (isActive)
      {
         workMode = MODE_AUTO;
      }
      changeMode(workMode);
      HAL_IWDG_Refresh(&hiwdg);
   }
}
//u8 str[]="ok";
void task_do_Transmit()
{
   bool ret=false;
   mask_relay_out = 0;
   //HAL_UART_Transmit(&huart1,str,2,100);
   com_transmit=new GW_RS485(&huart1, &htim6, &hdma_usart1_rx, &comSemHandle);
   com_transmit->enableIT();

   while (1)
   {
      osSemaphoreWait(comSemHandle, osWaitForever);
      if (workMode == MODE_AUTO)
      {
         ret = pol_Transmit.Matching(hdma_usart1_rx.Instance->CNDTR, com_transmit->recvbuf, moduleID, DIR_REQUEST);
         if (ret)
         {
            if (pol_Transmit.GetFunctionID() == MODBUS_WRITESIGCOIL)
            {
               mask_relay_out = pol_Transmit.GetRequestData();
               if (mask_relay_out!=0)
               {
                  relay_out.active();
               }
               else relay_out.unactive();
            }
         }
      }
      osDelay(1);
   }
}

void task_do_IO()
{
   while (1)
   {
      address.read((u8 *)&moduleID, sizeof(moduleID));
      relay_out.Tick(1);
      osDelay(100);
   }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
   if (UartHandle == com_transmit->uart)
   {
      com_transmit->beginRecv();
   }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   if (htim == com_transmit->tim)
   {
      com_transmit->timeout();
      //com_transmit->write(strbuf, 4);
   }
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
   osSemaphoreRelease(inputSemHandle);
}
